package org.domon.manager.sys.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.domon.manager.base.service.BaseService;
import org.domon.manager.common.WebConstants;
import org.domon.manager.sys.mapper.SysResourceMapper;
import org.domon.manager.sys.mapper.SysRole2ResourceMapper;
import org.domon.manager.sys.mapper.SysRoleMapper;
import org.domon.manager.sys.mapper.pojo.TSysMenu;
import org.domon.manager.sys.mapper.pojo.TSysResource;
import org.domon.manager.sys.mapper.pojo.TSysRole;
import org.domon.manager.sys.mapper.pojo.TSysRole2Resource;
import org.domon.manager.sys.model.Menu;
import org.domon.manager.sys.model.Role;
import org.domon.manager.sys.model.UserInfo;
import org.domon.manager.sys.service.SysRoleService;
import org.domon.manager.sys.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class SysRoleServiceImpl extends BaseService<Role, TSysRole> implements SysRoleService {

	@Autowired
	private SysRoleMapper sysRoleMapper;

	@Autowired
	private SysUserService sysUserService;

	@Autowired
	private SysRole2ResourceMapper sysRole2ResourceMapper;

	@Autowired
	private SysResourceMapper sysResourceMapper;

	@Override
	protected Role pojoToModel(TSysRole tSysRole) {
		Role role = new Role();
		role.setRoleId(tSysRole.getId());
		role.setRoleName(tSysRole.getRoleName());
		role.setRoleAlias(tSysRole.getRoleAlias());
		role.setCreator(sysUserService.queryById(tSysRole.getCrtBy()));
		role.setCrtTime(tSysRole.getCrtTime());
		return role;
	}

	@Override
	protected TSysRole modelToPojo(Role role) {
		TSysRole tSysRole = new TSysRole();
		if (role.getRoleId() != null) {
			tSysRole.setId(role.getRoleId());
		}
		tSysRole.setRoleName(role.getRoleName());
		tSysRole.setRoleAlias(role.getRoleAlias());
		return tSysRole;
	}

	@Override
	public Role save(Role role, UserInfo userInfo) {
		TSysRole tSysRole = modelToPojo(role);
		tSysRole.setCrtBy(userInfo.getUserId());
		tSysRole.setCrtTime(new Date());
		sysRoleMapper.insert(tSysRole);
		return pojoToModel(sysRoleMapper.selectById(tSysRole));
	}

	@Override
	public void saveMenu(int roleId, int[] menuIds, UserInfo userInfo) {
		// 菜单在资源表中的type
		String resourceType = (new TSysMenu()).getTable().getTableName();

		// 删除旧角色菜单
		List<TSysRole2Resource> sysRole2ResourceList = sysRole2ResourceMapper.selectByType(roleId, resourceType);
		for (TSysRole2Resource tSysRole2Resource : sysRole2ResourceList) {
			tSysRole2Resource.setWhereField("roleId", "resourceId");
			sysRole2ResourceMapper.delete(tSysRole2Resource);
		}

		// 插入角色根菜单
		TSysRole2Resource tSysRole2Resource = new TSysRole2Resource();
		tSysRole2Resource.setRoleId(roleId);
		tSysRole2Resource.setCrtBy(userInfo.getUserId());
		tSysRole2Resource.setCrtTime(new Date());
		tSysRole2Resource.setResourceId(WebConstants.BASE_MENU_ID);
		sysRole2ResourceMapper.insert(tSysRole2Resource);

		TSysResource tSysResource = new TSysResource();
		tSysResource.setType(resourceType);
		tSysResource.setWhereField("type", "joinId");
		for (int i = 0; i < menuIds.length; i++) {
			tSysResource.setJoinId(menuIds[i]);
			int resourceId = sysResourceMapper.select(tSysResource).get(0).getId();
			// 插入角色新菜单
			tSysRole2Resource.setResourceId(resourceId);
			sysRole2ResourceMapper.insert(tSysRole2Resource);
		}
	}

	@Override
	public void remove(int roleId) {
		TSysRole2Resource tSysRole2Resource = new TSysRole2Resource();
		tSysRole2Resource.setRoleId(roleId);
		tSysRole2Resource.setWhereField("roleId");
		sysRole2ResourceMapper.delete(tSysRole2Resource);

		TSysRole tSysRole = new TSysRole();
		tSysRole.setId(roleId);
		sysRoleMapper.deleteById(tSysRole);
	}

	@Override
	public List<Role> query(Role role) {
		TSysRole tSysRole = new TSysRole();
		List<TSysRole> sysRoleList = sysRoleMapper.select(tSysRole);

		List<Role> roleList = new ArrayList<Role>();
		for (TSysRole ttSysRole : sysRoleList) {
			role = this.pojoToModel(ttSysRole);

			roleList.add(role);
		}
		return roleList;
	}

	@Override
	public List<Role> queryByMenu(Menu menu) {
		TSysResource tSysResource = new TSysResource();
		tSysResource.setType((new TSysMenu()).getTable().getTableName());
		tSysResource.setWhereField("type", "joinId");
		tSysResource.setJoinId(menu.getMenuId());

		List<TSysResource> sysResourcesList = sysResourceMapper.select(tSysResource);
		int[] resourceIds = new int[sysResourcesList.size()];
		for (int i = 0; i < sysResourcesList.size(); i++) {
			resourceIds[i] = sysResourcesList.get(i).getId();
		}

		List<TSysRole> sysRoleList = sysRoleMapper.selectByResources(resourceIds);

		List<Role> roleList = new ArrayList<Role>();
		Role role = null;
		for (TSysRole ttSysRole : sysRoleList) {
			role = this.pojoToModel(ttSysRole);

			roleList.add(role);
		}
		return roleList;
	}
}
